﻿#define _CRT_SECURE_NO_WARNINGS 1
#include<iostream>

using namespace std;

// 浮点数、类对象以及字符串不允许作为非类型模板参数
// 非类型模板参数必须在编译期  就能确认结果
//namespace test 
//{
//	// 定义一个模板类型的静态数组
//	template<class T, size_t N = 10>
//	class array
//	{
//	public:
//		T& operator[](size_t index)
//		{
//			return _array[index];
//		}
//
//		const T& operator[](size_t index)const
//		{
//			return _array[index];
//		}
//
//		size_t size() const
//		{
//			return _size;
//		}
//
//		bool empty() const
//		{
//			return 0 == _size;
//		}
//
//	private:
//		T _array[N];
//		size_t _size;
//	};
//}
//int main()
//{
//	//test::array<int, 20> arr;
//
//	return 0;
//}

// 模板的特化
// 模板特化分为两种：函数模板特化、类模板特化

// 必须要先有一个基础的函数模板
// 关键字template后面接一对空的尖括号 < >
// 函数名后跟一对尖括号，尖括号中指定需要特化的类型
// 函数形参表: 必须要和模板函数的基础参数类型完全相同，如果不同编译器可能会报一些奇怪的错误


//template<class T>
//bool Less(T left, T right)
//{
//	return left < right;
//}
// 对Less函数模板进行特化
// 一般很少有，与其特化不如直接实现函数

//template<>
//bool Less<int*>(int* left, int* right)
//{
//	return *left < *right;
//}

//bool Less(Date* left, Date* right)
//{
//	return *left < *right;
//}

///////////////////////////////////////////////////////////////////////////////////////////////////
// 类模板特化

// 全特化
// 将模板参数列表中所有的参数都确定化
//template<class T1, class T2>
//class Data
//{
//public:
//	Data() { cout << "Data<T1, T2>" << endl; }
//private:
//	T1 _d1;
//	T2 _d2;
//};
//
//template<>
//class Data<int, char>
//{
//public:
//	Data() { cout << "Data<int, char>" << endl; }
//private:
//	int _d1;
//	char _d2;
//};
//

// 将第二个参数特化为int
//template <class T1>
//class Data<T1, int>
//{
//public:
//	Data() { cout << "Data<T1, int>" << endl; }
//private:
//	T1 _d1;
//	int _d2;
//};
//void Test()
//{
//	//Data<int, int> d1;
//	//Data<int, char> d2;
//}
//// 特化部分的意义，是针对模板参数更进一步的条件限制所设计出来的一个特化版本
//// 比如指针类型、引用类型
//
//int main()
//{
//	Test();
//	return 0;
//}
//////////////////////////////////////////////////////////////////////////////////////////////////
// 模板的分离编译
// 正常情况下模板是不能声明和定义分离的
// 如何解决？
// 1. 将声明和定义放在一个文件里，文件可以以.h结尾，或者.hpp结尾
// 2. 模板定义的位置显式实例化（不推荐）
// 模板的优点：
// 1. 模板复用了代码，节省资源，更快的迭代开发，C++的标准模板库(STL)因此而产生
// 2. 增强了代码的灵活性
// 缺点：
// 1. 模板会导致代码膨胀问题，也会导致编译时间变长
// 2. 出现模板编译错误时，错误信息非常凌乱，不易定位错误